/**
 * 
 */
package wangjg.commons.qrcode;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.ImageReader;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

/**
 * @author wangjg
 *
 */
public class QRCode {
	
	public static void encode(String contents, String filePath, int width, int height) throws Exception {
		MultiFormatWriter barcodeWriter = new MultiFormatWriter();
		BitMatrix matrix = barcodeWriter.encode(contents, BarcodeFormat.QR_CODE, width, height);
		MatrixToImageWriter.writeToPath(matrix, "PNG", new File(filePath).toPath());
	}
	
	public static void encode(String contents, OutputStream out, int width, int height) throws Exception {
		MultiFormatWriter barcodeWriter = new MultiFormatWriter();
		BitMatrix matrix = barcodeWriter.encode(contents, BarcodeFormat.QR_CODE, width, height);
		MatrixToImageWriter.writeToStream(matrix, "PNG", out);
	}
	
	public static String decode(URI uri) {
		BufferedImage image;
		try {
			image = ImageReader.readImage(uri);
		} catch (IOException ioe) {
			return ioe.toString();
		}
		LuminanceSource source = new BufferedImageLuminanceSource(image);
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
		Result result;
		try {
			result = new MultiFormatReader().decode(bitmap);
		} catch (ReaderException re) {
			return re.toString();
		}
		return String.valueOf(result.getText());
	}
	
	public static String decode(InputStream in) {
		BufferedImage image;
		try {
			image = ImageIO.read(in);
		} catch (IOException ioe) {
			return ioe.toString();
		}
		LuminanceSource source = new BufferedImageLuminanceSource(image);
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
		Result result;
		try {
			result = new MultiFormatReader().decode(bitmap);
		} catch (ReaderException re) {
			return re.toString();
		}
		return String.valueOf(result.getText());
	}
	
	public static void main(String[] args) throws Exception {
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<50;i++){
			sb.append("012345678A");
		}
		QRCode.encode(sb.toString(), "d:\\QRCode.png", 1600, 1600);
		String str = QRCode.decode(new File("d:\\QRCode.png").toURI());
		System.out.println(str);
	}
}
